package com.glc.lpp.simulation.workstation;

import com.glc.lpp.simulation.res.Equipment;
import com.glc.lpp.simulation.res.Operator;
import com.glc.lpp.simulation.res.Resource;
import com.glc.lpp.simulation.res.WorkSpace;

import java.util.HashMap;
import java.util.Map;

/**
 * 服务台
 *
 * @author demo
 * @version 2017-05-14
 */
public  class WorkStation {

    /**
     * 人员
     */
    public Operator operator;

    /**
     * 设备
     */
    public Equipment equip;

    /**
     * 工作区
     */
    public WorkSpace space;

    /**
     * 等待队列
     */
    public int waitQueue;

    private Map<Integer, Integer> goodsMap;//到货/出货记录

    /**
     * 处理过程
     */
    protected Map<Integer, Integer> procedure = new HashMap<Integer, Integer>();

    /**
     * 下一个流程服务台
     */
    protected WorkStation next;

    public WorkStation(Operator operator, Equipment equip, WorkSpace space) {
        this.operator = operator;
        this.equip = equip;
        this.space = space;
    }

    public void setNextWorkStation(WorkStation next) {
        this.next = next;
    }

    public void setGoodsMap(Map<Integer, Integer> goodsMap) {
        this.goodsMap = goodsMap;
    }

    /**
     * 服务接收
     *
     * @param time 货物记录
     */
    public void receiveGoods(int time) {
        if (goodsMap != null) {
            Integer amount = goodsMap.get(time);
            if (amount != null) {
                receive(amount);
                goodsMap.remove(time);
            }
        }
    }

    /**
     * 服务接收上个环节处理完的货物
     *
     * @param amount 队列元素量
     */
    public void receive(int amount) {
        waitQueue += amount;
    }

    /**
     * 仿真模拟开始
     *
     * @param start 时间
     */
    public final void start(int start) {
        int used = 0;
        while (waitQueue > 0) {
            synchronized (Resource.class) {
                if (!free(1)) {
                    break;
                }
                use(1);
            }
            used++;
            waitQueue -= 1;//等待队列减少
        }
        if (used > 0) {
            //  waitQueue = waitQueue - used;
            procedure.put(start + operator.ability - 1, used);//加入处理过程
        }
    }

    /**
     * 工作台是否有空闲处理
     *
     * @return
     */
    public boolean free(int amount) {
        if (operator != Operator.NULL && operator.available - amount < 0) {
            return false;
        }
        if (equip != Equipment.NULL && equip.available - amount < 0) {
            return false;
        }
        if (space != WorkSpace.NULL && space.available - amount < 0) {
            return false;
        }
        return true;
    }

    /**
     * 使用服务资源
     *
     * @return
     */
    public  void use(int amount){
        if (operator != Operator.NULL ) {
            operator.use(amount);
        }
        if (equip != Equipment.NULL) {
            equip.use(amount);
        }
        if (space != WorkSpace.NULL) {
            space.use(amount);
        }
    }

    /**
     * 仿真模拟结束
     *
     * @param time 服务结束时间
     */
    public void end(int time) {
        Integer releaseServant = procedure.get(time);
        if (releaseServant != null) {
            if (next != null) {//加入下一个服务台
                next.receive(releaseServant);
            }
            synchronized (Resource.class) {
                restore(releaseServant);
            }
            procedure.remove(time);
        }
    }

    /**
     * 归还资源
     *
     * @param amount 资源数
     */
    public void restore(int amount){
        if (operator != Operator.NULL ) {
            operator.restore(amount);
        }
        if (equip != Equipment.NULL) {
            equip.restore(amount);
        }
        if (space != WorkSpace.NULL) {
            space.restore(amount);
        }
    }

    /**
     * 服务台是否运转
     *
     * @return
     */
    public boolean working() {
        if (goodsMap != null && goodsMap.size() > 0) {
            return true;
        }
        return waitQueue > 0 || procedure.size() > 0;
    }
}
